Skip to content

Fix webpack loader cache key for resource queries#19723

Merged
RobinMalfait merged 4 commits intotailwindlabs:mainfrom
colinaaa:fix-webpack-loader-resource-cache
Mar 20, 2026
Merged

Fix webpack loader cache key for resource queries#19723
RobinMalfait merged 4 commits intotailwindlabs:mainfrom
colinaaa:fix-webpack-loader-resource-cache

Conversation

@colinaaa
Copy link
Contributor

Summary

@tailwindcss/webpack currently uses this.resourcePath as the cache key, which ignores the resource query. When the same CSS file is imported multiple times with different resourceQuery values, all of those imports share a single CacheEntry. That means the utilities discovered for one entry can leak into the CSS output for another entry.

This PR changes the cache key to use this.resource (path + query) instead, while still using this.resourcePath for all filesystem work.

Test plan

  • pnpm test:integrations -- webpack/loader.test.ts
    • Confirms all existing webpack loader integration tests pass.
    • Confirms the new @tailwindcss/webpack loader isolates cache by resource including query test passes, verifying that two entries importing the same CSS file with different queries produce isolated outputs (dist/a.css only contains only-a / --color-red-500, and dist/b.css only contains only-b / --color-blue-500).

@colinaaa colinaaa requested a review from a team as a code owner February 25, 2026 06:48
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 09b6367c-a169-4711-9d71-06a6ea448636

📥 Commits

Reviewing files that changed from the base of the PR and between e601055 and 3fdc74e.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • integrations/webpack/loader.test.ts
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • integrations/webpack/loader.test.ts

Walkthrough

The Webpack loader's cache handling was refactored to derive cache keys from resource identifiers via a new helper getCacheKey. getContextFromCache now accepts resourceId instead of inputFile, and internal calls were updated accordingly. The loader captures resourceId from this.resource and uses it when obtaining and clearing cache entries. A new integration test verifies cache isolation for imports with different resource query strings.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix webpack loader cache key for resource queries' accurately summarizes the main change: refactoring the webpack loader to use resource queries (path + query) instead of just resource path for cache key derivation.
Description check ✅ Passed The description is directly related to the changeset, clearly explaining the problem (cache key ignoring resource queries causing utility leakage), the solution (using this.resource instead of this.resourcePath), and test verification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/@tailwindcss-webpack/src/index.ts (1)

43-45: Consider a collision-proof separator for the composite cache key.

The : delimiter is also present in Windows drive-letter paths (e.g., opts.base = "C:/some/dir"), making the key format theoretically ambiguous. In practice this is unlikely to cause a collision today, but the fix is trivial.

♻️ Suggested improvement
 function getCacheKey(resourceId: string, opts: LoaderOptions): string {
-  return `${resourceId}:${opts.base ?? ''}:${JSON.stringify(opts.optimize)}`
+  return JSON.stringify([resourceId, opts.base ?? '', opts.optimize ?? null])
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/`@tailwindcss-webpack/src/index.ts around lines 43 - 45, The
composite cache key in getCacheKey(resourceId, opts) uses ":" which can collide
with Windows drive letters; update getCacheKey to produce an unambiguous
key—either by using a collision-proof separator (e.g., a null character '\u0000'
or an unlikely token) between resourceId, opts.base and
JSON.stringify(opts.optimize), or simply serialize the whole object (e.g.,
JSON.stringify({resourceId, base: opts.base ?? '', optimize: opts.optimize})) so
the key is unambiguous; change the implementation in getCacheKey to use one of
these approaches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/`@tailwindcss-webpack/src/index.ts:
- Around line 43-45: The composite cache key in getCacheKey(resourceId, opts)
uses ":" which can collide with Windows drive letters; update getCacheKey to
produce an unambiguous key—either by using a collision-proof separator (e.g., a
null character '\u0000' or an unlikely token) between resourceId, opts.base and
JSON.stringify(opts.optimize), or simply serialize the whole object (e.g.,
JSON.stringify({resourceId, base: opts.base ?? '', optimize: opts.optimize})) so
the key is unambiguous; change the implementation in getCacheKey to use one of
these approaches.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 097f982 and e601055.

📒 Files selected for processing (2)
  • integrations/webpack/loader.test.ts
  • packages/@tailwindcss-webpack/src/index.ts

Copy link
Member

@RobinMalfait RobinMalfait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the integration test to make it pass in CI. The \n were causing a bit of issues because we were embedding it in JS to write to the file, so I think we should've used \\n but I got rid of it anyway.

Thanks!

@RobinMalfait RobinMalfait enabled auto-merge (squash) March 20, 2026 16:32
@RobinMalfait RobinMalfait merged commit 17d324f into tailwindlabs:main Mar 20, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants